home *** CD-ROM | disk | FTP | other *** search
/ Programming a Multiplayer FPS in DirectX / Programming a Multiplayer FPS in DirectX (Companion CD).iso / DirectX / dxsdk_oct2004.exe / dxsdk.exe / Samples / C++ / Direct3D / DXTex / dxtexview.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2004-09-27  |  30.3 KB  |  1,101 lines

  1. // dxtexView.cpp : implementation of the CDxtexView class
  2. //
  3.  
  4. #include "stdafx.h"
  5. #include "dxtex.h"
  6. #include "formats.h"
  7. #include "dxtexDoc.h"
  8. #include "dxtexView.h"
  9.  
  10. #ifdef _DEBUG
  11. #define new DEBUG_NEW
  12. #undef THIS_FILE
  13. static char THIS_FILE[] = __FILE__;
  14. #endif
  15.  
  16. // Our custom vertex type
  17. struct CUSTOMVERTEX
  18. {
  19.     FLOAT x, y, z;
  20.     FLOAT rhw;
  21.     DWORD color;
  22.     FLOAT tu, tv;   // The texture coordinates
  23. };
  24.  
  25. #define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_TEX1)
  26.  
  27.  
  28. IMPLEMENT_DYNCREATE(CDxtexView, CScrollView)
  29.  
  30. BEGIN_MESSAGE_MAP(CDxtexView, CScrollView)
  31.     //{{AFX_MSG_MAP(CDxtexView)
  32.     ON_WM_LBUTTONUP()
  33.     ON_COMMAND(ID_FILE_OPENSUBSURFACE, OnFileOpenSubsurface)
  34.     ON_COMMAND(ID_FILE_OPENALPHASUBSURFACE, OnFileOpenAlphaSubsurface)
  35.     ON_COMMAND(ID_FILE_OPENFACE, OnFileOpenFace)
  36.     ON_COMMAND(ID_FILE_OPENALPHAFACE, OnFileOpenAlphaFace)
  37.     ON_COMMAND(ID_VIEW_ORIGINAL, OnViewOriginal)
  38.     ON_COMMAND(ID_VIEW_COMPRESSED, OnViewCompressed)
  39.     ON_COMMAND(ID_VIEW_SMALLERMIPLEVEL, OnViewSmallerMipLevel)
  40.     ON_COMMAND(ID_VIEW_LARGERMIPLEVEL, OnViewLargerMipLevel)
  41.     ON_COMMAND(ID_VIEW_ALPHACHANNEL, OnViewAlphaChannel)
  42.     ON_COMMAND(ID_VIEW_ZOOMIN, OnViewZoomIn)
  43.     ON_COMMAND(ID_VIEW_ZOOMOUT, OnViewZoomOut)
  44.     ON_COMMAND(ID_VIEW_CHANGEBACKGROUNDCOLOR, OnViewChangeBackgroundColor)
  45.     ON_COMMAND(ID_VIEW_NEGX, OnViewNegX)
  46.     ON_COMMAND(ID_VIEW_POSX, OnViewPosX)
  47.     ON_COMMAND(ID_VIEW_NEGY, OnViewNegY)
  48.     ON_COMMAND(ID_VIEW_POSY, OnViewPosY)
  49.     ON_COMMAND(ID_VIEW_NEGZ, OnViewNegZ)
  50.     ON_COMMAND(ID_VIEW_POSZ, OnViewPosZ)
  51.     ON_COMMAND(ID_VIEW_HIGHERVOLUMESLICE, OnViewHigherVolumeSlice)
  52.     ON_COMMAND(ID_VIEW_LOWERVOLUMESLICE, OnViewLowerVolumeSlice)
  53.     ON_UPDATE_COMMAND_UI(ID_FILE_OPENSUBSURFACE, OnUpdateFileOpenSubsurface)
  54.     ON_UPDATE_COMMAND_UI(ID_FILE_OPENALPHASUBSURFACE, OnUpdateFileOpenAlphaSubsurface)
  55.     ON_UPDATE_COMMAND_UI(ID_FILE_OPENFACE, OnUpdateFileOpenFace)
  56.     ON_UPDATE_COMMAND_UI(ID_FILE_OPENALPHAFACE, OnUpdateFileOpenAlphaFace)
  57.     ON_UPDATE_COMMAND_UI(ID_VIEW_ORIGINAL, OnUpdateViewOriginal)
  58.     ON_UPDATE_COMMAND_UI(ID_VIEW_COMPRESSED, OnUpdateViewCompressed)
  59.     ON_UPDATE_COMMAND_UI(ID_VIEW_ALPHACHANNEL, OnUpdateViewAlphaChannel)
  60.     ON_UPDATE_COMMAND_UI(ID_VIEW_LARGERMIPLEVEL, OnUpdateViewLargerMipLevel)
  61.     ON_UPDATE_COMMAND_UI(ID_VIEW_SMALLERMIPLEVEL, OnUpdateViewSmallerMipLevel)
  62.     ON_UPDATE_COMMAND_UI(ID_VIEW_ZOOMIN, OnUpdateViewZoomIn)
  63.     ON_UPDATE_COMMAND_UI(ID_VIEW_ZOOMOUT, OnUpdateViewZoomOut)
  64.     ON_UPDATE_COMMAND_UI(ID_VIEW_NEGX, OnUpdateViewNegX)
  65.     ON_UPDATE_COMMAND_UI(ID_VIEW_POSX, OnUpdateViewPosX)
  66.     ON_UPDATE_COMMAND_UI(ID_VIEW_NEGY, OnUpdateViewNegY)
  67.     ON_UPDATE_COMMAND_UI(ID_VIEW_POSY, OnUpdateViewPosY)
  68.     ON_UPDATE_COMMAND_UI(ID_VIEW_NEGZ, OnUpdateViewNegZ)
  69.     ON_UPDATE_COMMAND_UI(ID_VIEW_POSZ, OnUpdateViewPosZ)
  70.     ON_UPDATE_COMMAND_UI(ID_VIEW_HIGHERVOLUMESLICE, OnUpdateViewHigherVolumeSlice)
  71.     ON_UPDATE_COMMAND_UI(ID_VIEW_LOWERVOLUMESLICE, OnUpdateViewLowerVolumeSlice)
  72.     //}}AFX_MSG_MAP
  73. END_MESSAGE_MAP()
  74.  
  75. static UINT GetSurfaceSize(D3DSURFACE_DESC* pDesc)
  76. {
  77.     UINT nSurfaceSize = 0;
  78.  
  79.     for( int i=0; i < fmtInfoArraySize; i++ )
  80.     {
  81.         if( fmtInfoArray[i].fmt == pDesc->Format )
  82.         {
  83.             nSurfaceSize = pDesc->Width * 
  84.                            pDesc->Height * 
  85.                            fmtInfoArray[i].nBitsPerTexel / sizeof(BYTE);
  86.                                     
  87.             break;
  88.         }
  89.     }
  90.  
  91.     return nSurfaceSize;
  92. }
  93.  
  94. static UINT GetVolumeSize(D3DVOLUME_DESC* pDesc)
  95. {
  96.     UINT nSurfaceSize = 0;
  97.  
  98.     for( int i=0; i < fmtInfoArraySize; i++ )
  99.     {
  100.         if( fmtInfoArray[i].fmt == pDesc->Format )
  101.         {
  102.             nSurfaceSize = pDesc->Width * 
  103.                            pDesc->Height *
  104.                            pDesc->Depth *
  105.                            fmtInfoArray[i].nBitsPerTexel / sizeof(BYTE);
  106.  
  107.             break;
  108.         }
  109.     }
  110.  
  111.     return nSurfaceSize;
  112. }
  113.  
  114.  
  115. CDxtexView::CDxtexView()
  116. {
  117.     m_pVB = NULL;
  118.     m_ptexCur = NULL;
  119.     m_pSwapChain = NULL;
  120.     m_lwMipCur = 0;
  121.     m_CubeFaceCur = D3DCUBEMAP_FACE_FORCE_DWORD;
  122.     m_lwSliceCur = -1;
  123.     m_fZoom = 1.0f;
  124.     m_bViewOrig = TRUE;
  125.     m_bViewAlpha = FALSE;
  126. }
  127.  
  128.  
  129. CDxtexView::~CDxtexView()
  130. {
  131.     ReleasePpo(&m_pVB);
  132.     ReleasePpo(&m_ptexCur);
  133.     ReleasePpo(&m_pSwapChain);
  134. }
  135.  
  136.  
  137. // Note: repaints don't require re-rendering, just recopy from back buffer to view's DC
  138. void CDxtexView::OnDraw(CDC* pDC)
  139. {
  140.     CDxtexDoc* pDoc = GetDocument();
  141.     ASSERT_VALID(pDoc);
  142.  
  143.     HRESULT hr;
  144.     CRect rcSrc;
  145.     CRect rcDest;
  146.  
  147.     rcSrc = m_rcSrc;
  148.     rcDest = m_rcDest;
  149.  
  150.     rcDest.OffsetRect(pDC->GetViewportOrg());
  151.  
  152.     // REVIEW: only update dirty region?
  153.     if (m_pSwapChain != NULL)
  154.     {
  155.         if( PDxtexApp()->HandlePossibleLostDevice() )
  156.         {
  157.             hr = m_pSwapChain->Present(&rcSrc, &rcDest, GetSafeHwnd(), NULL, 0);
  158.             if( hr == D3DERR_DEVICELOST )
  159.             {
  160.                 PDxtexApp()->DeviceIsLost();
  161.                 Invalidate();
  162.             }
  163.         }
  164.     }
  165. }
  166.  
  167.  
  168. #ifdef _DEBUG
  169. void CDxtexView::AssertValid() const
  170. {
  171.     CScrollView::AssertValid();
  172. }
  173.  
  174.  
  175. void CDxtexView::Dump(CDumpContext& dc) const
  176. {
  177.     CScrollView::Dump(dc);
  178. }
  179.  
  180.  
  181. CDxtexDoc* CDxtexView::GetDocument() // non-debug version is inline
  182. {
  183.     ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CDxtexDoc)));
  184.     return (CDxtexDoc*)m_pDocument;
  185. }
  186. #endif //_DEBUG
  187.  
  188.  
  189. void CDxtexView::OnLButtonUp(UINT nFlags, CPoint point)
  190. {
  191.     // Button click means toggle compressed / uncompressed view
  192.     if (m_bViewOrig)
  193.         OnViewCompressed();
  194.     else
  195.         OnViewOriginal();
  196.  
  197.     CScrollView::OnLButtonUp(nFlags, point);
  198. }
  199.  
  200.  
  201. void CDxtexView::OnInitialUpdate()
  202. {
  203. #ifdef _WIN64
  204.     SetClassLongPtr(GetSafeHwnd(), GCLP_HBRBACKGROUND, (LONG_PTR)CreateSolidBrush(RGB(100, 100, 120)));
  205. #else
  206.     SetClassLong(GetSafeHwnd(), GCL_HBRBACKGROUND, (LONG)CreateSolidBrush(RGB(100, 100, 120)));
  207. #endif
  208.  
  209.     if (GetDocument()->IsCubeMap())
  210.         m_CubeFaceCur = D3DCUBEMAP_FACE_POSITIVE_X;
  211.     else
  212.         m_CubeFaceCur = D3DCUBEMAP_FACE_FORCE_DWORD;
  213.     if (GetDocument()->IsVolumeMap())
  214.         m_lwSliceCur = 0;
  215.     BuildViewSurface(m_bViewOrig, m_CubeFaceCur, m_lwSliceCur, m_lwMipCur, m_bViewAlpha);
  216.     UpdateDevice();
  217.     CreateVertexBuffer();
  218.     RenderScene();
  219.  
  220.     SetScrollSizes(MM_TEXT, CSize(m_rcDest.Width(), m_rcDest.Height()));
  221.     ResizeParentToFit();
  222.  
  223.     CScrollView::OnInitialUpdate();
  224.  
  225.     m_bTitleModsChanged = TRUE; // force title bar update
  226. }
  227.  
  228.  
  229. VOID CDxtexView::GetImageInfo(CString& strInfo)
  230. {
  231.     LPDIRECT3DBASETEXTURE9 ptex;
  232.     D3DSURFACE_DESC sd;
  233.     D3DVOLUME_DESC vd;
  234.     D3DFORMAT fmt;
  235.     DWORD dwWidth;
  236.     DWORD dwHeight;
  237.     DWORD dwDepth;
  238.     CString strFormat;
  239.     TCHAR sz[100];
  240.     DWORD dwBytes = 0;
  241.     UINT iLevel;
  242.  
  243.     if (m_bViewOrig)
  244.         ptex = GetDocument()->PtexOrig();
  245.     else
  246.         ptex = GetDocument()->PtexNew();
  247.  
  248.     if (GetDocument()->IsVolumeMap())
  249.     {
  250.         ((LPDIRECT3DVOLUMETEXTURE9)ptex)->GetLevelDesc(0, &vd);
  251.         fmt = vd.Format;
  252.         dwWidth = vd.Width;
  253.         dwHeight = vd.Height;
  254.         dwDepth = vd.Depth;
  255.     }
  256.     else if (!GetDocument()->IsCubeMap())
  257.     {
  258.         ((LPDIRECT3DTEXTURE9)ptex)->GetLevelDesc(0, &sd);
  259.         fmt = sd.Format;
  260.         dwWidth = sd.Width;
  261.         dwHeight = sd.Height;
  262.         dwDepth = 0;
  263.     }
  264.     else
  265.     {
  266.         ((LPDIRECT3DCUBETEXTURE9)ptex)->GetLevelDesc(0, &sd);
  267.         fmt = sd.Format;
  268.         dwWidth = sd.Width;
  269.         dwHeight = sd.Height;
  270.         dwDepth = 0;
  271.     }
  272.  
  273.     strFormat = FormatName(fmt);
  274.  
  275.     // Count bytes in main surface chain
  276.     if (GetDocument()->IsVolumeMap())
  277.     {
  278.         for (iLevel = 0; iLevel < GetDocument()->NumMips(); iLevel++)
  279.         {
  280.             ((LPDIRECT3DVOLUMETEXTURE9)ptex)->GetLevelDesc(iLevel, &vd);
  281.             dwBytes += GetVolumeSize(&vd);
  282.         }
  283.     }
  284.     else if (!GetDocument()->IsCubeMap())
  285.     {
  286.         dwBytes += NumBytesInSurfaces(D3DCUBEMAP_FACE_FORCE_DWORD, ptex);
  287.     }
  288.     else
  289.     {
  290.         dwBytes += NumBytesInSurfaces(D3DCUBEMAP_FACE_POSITIVE_X, ptex);
  291.         dwBytes += NumBytesInSurfaces(D3DCUBEMAP_FACE_NEGATIVE_X, ptex);
  292.         dwBytes += NumBytesInSurfaces(D3DCUBEMAP_FACE_POSITIVE_Y, ptex);
  293.         dwBytes += NumBytesInSurfaces(D3DCUBEMAP_FACE_NEGATIVE_Y, ptex);
  294.         dwBytes += NumBytesInSurfaces(D3DCUBEMAP_FACE_POSITIVE_Z, ptex);
  295.         dwBytes += NumBytesInSurfaces(D3DCUBEMAP_FACE_NEGATIVE_Z, ptex);
  296.     }
  297.  
  298.     if (dwDepth == 0)
  299.         wsprintf(sz, "%d x %d, %s, %d bytes", dwWidth, dwHeight, (LPCTSTR)strFormat, dwBytes);
  300.     else
  301.         wsprintf(sz, "%d x %d x %d, %s, %d bytes", dwWidth, dwHeight, dwDepth, (LPCTSTR)strFormat, dwBytes);
  302.     strInfo = sz;
  303. }
  304.  
  305.  
  306. DWORD CDxtexView::NumBytesInSurfaces(D3DCUBEMAP_FACES FaceType, LPDIRECT3DBASETEXTURE9 ptex)
  307. {
  308.     DWORD dwBytes = 0;
  309.     LPDIRECT3DTEXTURE9 pmiptex = NULL;
  310.     LPDIRECT3DCUBETEXTURE9 pcubetex = NULL;
  311.     D3DSURFACE_DESC sd;
  312.     DWORD iLevel;
  313.  
  314.     if (FaceType == D3DCUBEMAP_FACE_FORCE_DWORD)
  315.         pmiptex = (LPDIRECT3DTEXTURE9)ptex;
  316.     else
  317.         pcubetex = (LPDIRECT3DCUBETEXTURE9)ptex;
  318.  
  319.     for (iLevel = 0; iLevel < GetDocument()->NumMips(); iLevel++)
  320.     {
  321.         if (pmiptex != NULL)
  322.             pmiptex->GetLevelDesc(iLevel, &sd);
  323.         else
  324.             pcubetex->GetLevelDesc(iLevel, &sd);
  325.         dwBytes += GetSurfaceSize(&sd);
  326.     }
  327.  
  328.     return dwBytes;
  329. }
  330.  
  331.  
  332. HRESULT CDxtexView::UpdateDevice(VOID)
  333. {
  334.     HRESULT hr;
  335.     LPDIRECT3D9 pd3d = PDxtexApp()->Pd3d();
  336.     LPDIRECT3DDEVICE9 pd3ddev = PDxtexApp()->Pd3ddev();
  337.     D3DDISPLAYMODE dispMode;
  338.     D3DPRESENT_PARAMETERS presentParams;
  339.  
  340.     pd3d->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &dispMode);
  341.  
  342.     ReleasePpo(&m_pSwapChain);
  343.     ZeroMemory(&presentParams, sizeof(presentParams));
  344.     presentParams.Windowed = TRUE;
  345.     presentParams.SwapEffect = D3DSWAPEFFECT_COPY;
  346.     presentParams.BackBufferWidth = m_rcSrc.Width();
  347.     presentParams.BackBufferHeight = m_rcSrc.Height();
  348.     presentParams.BackBufferFormat = dispMode.Format;
  349.  
  350.     if (FAILED(hr = pd3ddev->CreateAdditionalSwapChain(&presentParams, &m_pSwapChain)))
  351.         return hr;
  352.  
  353.     COLORREF crBkgd;
  354.     crBkgd = PDxtexApp()->GetProfileInt("Settings", "Background Color", RGB(0, 255, 255));
  355.     m_dwClearColor = D3DCOLOR_RGBA(GetRValue(crBkgd), GetGValue(crBkgd), GetBValue(crBkgd), 255);
  356.  
  357.     return S_OK;
  358. }
  359.  
  360. HRESULT CDxtexView::InvalidateDeviceObjects(VOID)
  361. {
  362.     ReleasePpo( &m_pSwapChain );
  363.     return S_OK;
  364. }
  365.  
  366. HRESULT CDxtexView::RestoreDeviceObjects(VOID)
  367. {
  368.     UpdateDevice();
  369.     RenderScene();
  370.     Invalidate();
  371.     return S_OK;
  372. }
  373.  
  374. HRESULT CDxtexView::CreateVertexBuffer(VOID)
  375. {
  376.     LPDIRECT3DDEVICE9 pd3ddev = PDxtexApp()->Pd3ddev();
  377.  
  378.     // Create the the vertex buffer
  379.     if( FAILED( pd3ddev->CreateVertexBuffer( 6 * sizeof(CUSTOMVERTEX),
  380.         0 /* Usage */, D3DFVF_CUSTOMVERTEX, 
  381.         D3DPOOL_MANAGED, &m_pVB, NULL ) ) )
  382.     {
  383.         return E_FAIL;
  384.     }
  385.  
  386.     return S_OK;
  387. }
  388.  
  389.  
  390. HRESULT CDxtexView::RenderScene(VOID)
  391. {
  392.     CWaitCursor waitCursor;
  393.     HRESULT hr;
  394.     LPDIRECT3DDEVICE9 pd3ddev = PDxtexApp()->Pd3ddev();
  395.  
  396.     LPDIRECT3DSURFACE9 psurf;
  397.  
  398.     if (m_pSwapChain == NULL)
  399.         return E_FAIL;
  400.  
  401.     // Vertices for our quad
  402.     CUSTOMVERTEX vertexArray[] =
  403.     {
  404.         // x, y, z, rhw, color
  405.         { -0.5f,                     -0.5f,                      0.5f, 1.0f, 0xffffffff, 0.0, 0.0, },
  406.         { (FLOAT)m_rcSrc.right-0.5f, -0.5f,                      0.5f, 1.0f, 0xffffffff, 1.0, 0.0, },
  407.         { (FLOAT)m_rcSrc.right-0.5f, (FLOAT)m_rcSrc.bottom-0.5f, 0.5f, 1.0f, 0xffffffff, 1.0, 1.0, },
  408.  
  409.         { (FLOAT)m_rcSrc.right-0.5f, (FLOAT)m_rcSrc.bottom-0.5f, 0.5f, 1.0f, 0xffffffff, 1.0, 1.0, },
  410.         { -0.5f,                     (FLOAT)m_rcSrc.bottom-0.5f, 0.5f, 1.0f, 0xffffffff, 0.0, 1.0, },
  411.         { -0.5f,                     -0.5f,                      0.5f, 1.0f, 0xffffffff, 0.0, 0.0, },
  412.     };
  413.  
  414.     // Copy the global vertex data into the vertex buffer
  415.     VOID* pVertices;
  416.     if( FAILED( m_pVB->Lock( 0, sizeof(vertexArray), (void**)&pVertices, 0 ) ) )
  417.         return E_FAIL;
  418.     memcpy( pVertices, vertexArray, sizeof(vertexArray) );
  419.     m_pVB->Unlock();
  420.  
  421.     hr = m_pSwapChain->GetBackBuffer(0, D3DBACKBUFFER_TYPE_MONO, &psurf);
  422.  
  423.     hr = pd3ddev->SetRenderTarget(0, psurf);
  424.  
  425.     ReleasePpo(&psurf);
  426.  
  427.     hr = pd3ddev->Clear(0, NULL, D3DCLEAR_TARGET, m_dwClearColor, 0.0f, 0);
  428.  
  429.     hr = pd3ddev->BeginScene();
  430.  
  431.     // If the texture uses premultiplied alpha, the source blend should be D3DBLEND_ONE
  432.     // since RGB is already at the level we want.  With nonpremultiplied alpha, the
  433.     // source blend should be D3DBLEND_SRCALPHA.
  434.     D3DSURFACE_DESC sd;
  435.     m_ptexCur->GetLevelDesc(0, &sd);
  436.     if (!m_bViewAlpha && (sd.Format == D3DFMT_DXT2 || sd.Format == D3DFMT_DXT4))
  437.     {
  438.         if (FAILED(hr = pd3ddev->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_ONE)))
  439.             return hr;
  440.     }
  441.     else
  442.     {
  443.         if (FAILED(hr = pd3ddev->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA)))
  444.             return hr;
  445.     }
  446.     hr = pd3ddev->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
  447.     hr = pd3ddev->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
  448.  
  449.     pd3ddev->SetTexture(0, m_ptexCur);
  450.     pd3ddev->SetStreamSource( 0, m_pVB, 0, sizeof(CUSTOMVERTEX) );
  451.     pd3ddev->SetFVF( D3DFVF_CUSTOMVERTEX );
  452.     pd3ddev->DrawPrimitive( D3DPT_TRIANGLELIST, 0, 2 );
  453.     pd3ddev->SetTexture(0, NULL);
  454.  
  455.     hr = pd3ddev->EndScene();
  456.  
  457.     return S_OK;
  458. }
  459.  
  460.  
  461. void CDxtexView::OnViewOriginal()
  462. {
  463.     if (GetDocument()->PtexOrig() == NULL)
  464.         return;
  465.     BuildViewSurface(TRUE, m_CubeFaceCur, m_lwSliceCur, m_lwMipCur, m_bViewAlpha);
  466.     RenderScene();
  467.     m_bTitleModsChanged = TRUE; // force title bar update
  468.     InvalidateRect(&m_rcDest, FALSE); // force redraw of this view
  469. }
  470.  
  471.  
  472. void CDxtexView::OnViewCompressed()
  473. {
  474.     if (GetDocument()->PtexNew() == NULL)
  475.         return;
  476.     BuildViewSurface(FALSE, m_CubeFaceCur, m_lwSliceCur, m_lwMipCur, m_bViewAlpha);
  477.     RenderScene();
  478.     m_bTitleModsChanged = TRUE; // force title bar update
  479.     InvalidateRect(&m_rcDest, FALSE); // force redraw of this view
  480. }
  481.  
  482.  
  483. void CDxtexView::OnUpdateViewOriginal(CCmdUI* pCmdUI)
  484. {
  485.     if (GetDocument()->PtexOrig() == NULL)
  486.     {
  487.         pCmdUI->Enable(FALSE);
  488.         pCmdUI->SetCheck(0);
  489.     }
  490.     else
  491.     {
  492.         pCmdUI->Enable(TRUE);
  493.         pCmdUI->SetCheck(m_bViewOrig);
  494.     }
  495. }
  496.  
  497.  
  498. void CDxtexView::OnUpdateViewCompressed(CCmdUI* pCmdUI)
  499. {
  500.     if (GetDocument()->PtexNew() == NULL)
  501.     {
  502.         pCmdUI->Enable(FALSE);
  503.         pCmdUI->SetCheck(0);
  504.     }
  505.     else
  506.     {
  507.         pCmdUI->Enable(TRUE);
  508.         pCmdUI->SetCheck(!m_bViewOrig);
  509.     }
  510. }
  511.  
  512.  
  513. void CDxtexView::OnUpdate(CView* pSender, LPARAM lHint, CObject* pHint)
  514. {
  515.     m_bTitleModsChanged = TRUE; // force title bar update
  516.     if (lHint == 1)
  517.     {
  518.         BuildViewSurface(m_bViewOrig, m_CubeFaceCur, m_lwSliceCur, m_lwMipCur, m_bViewAlpha);
  519.         RenderScene();
  520.     }
  521.     else if (lHint == 2)
  522.     {
  523.         UpdateDevice();
  524.         RenderScene();
  525.     }
  526.     else if (lHint == 3)
  527.     {
  528.         RenderScene();
  529.     }
  530.     else if( lHint == 4)
  531.     {
  532.         BuildViewSurface(m_bViewOrig, m_CubeFaceCur, m_lwSliceCur, m_lwMipCur, m_bViewAlpha);
  533.         UpdateDevice();
  534.         RenderScene();
  535.         SetScrollSizes(MM_TEXT, CSize(m_rcDest.Width(), m_rcDest.Height()));
  536.         ResizeParentToFit();
  537.     }
  538.  
  539.     CScrollView::OnUpdate(pSender, lHint, pHint);
  540. }
  541.  
  542.  
  543. void CDxtexView::OnViewSmallerMipLevel()
  544. {
  545.     m_lwMipCur++;
  546.     if (m_lwSliceCur > 0)
  547.         m_lwSliceCur /= 2;
  548.     BuildViewSurface(m_bViewOrig, m_CubeFaceCur, m_lwSliceCur, m_lwMipCur, m_bViewAlpha);
  549.     UpdateDevice();
  550.     RenderScene();
  551.     m_bTitleModsChanged = TRUE; // force title bar update
  552.     SetScrollSizes(MM_TEXT, CSize(m_rcDest.Width(), m_rcDest.Height()));
  553.     Invalidate(); // force redraw of this view
  554. }
  555.  
  556.  
  557. void CDxtexView::OnViewLargerMipLevel()
  558. {
  559.     m_lwMipCur--;
  560.     if (m_lwSliceCur > 0)
  561.         m_lwSliceCur *= 2;
  562.     BuildViewSurface(m_bViewOrig, m_CubeFaceCur, m_lwSliceCur, m_lwMipCur, m_bViewAlpha);
  563.     UpdateDevice();
  564.     RenderScene();
  565.     m_bTitleModsChanged = TRUE; // force title bar update
  566.     SetScrollSizes(MM_TEXT, CSize(m_rcDest.Width(), m_rcDest.Height()));
  567.     Invalidate(); // force redraw of this view
  568. }
  569.  
  570.  
  571. void CDxtexView::OnViewAlphaChannel(VOID)
  572. {
  573.     BuildViewSurface(m_bViewOrig, m_CubeFaceCur, m_lwSliceCur, m_lwMipCur, !m_bViewAlpha);
  574.     RenderScene();
  575.     Invalidate(); // force redraw of this view
  576.     m_bTitleModsChanged = TRUE; // force title bar update
  577. }
  578.  
  579.  
  580. void CDxtexView::OnUpdateViewAlphaChannel(CCmdUI* pCmdUI)
  581. {
  582.     pCmdUI->SetCheck(m_bViewAlpha);
  583. }
  584.  
  585.  
  586. void CDxtexView::OnUpdateViewLargerMipLevel(CCmdUI* pCmdUI)
  587. {
  588.     if (m_lwMipCur > 0)
  589.         pCmdUI->Enable(TRUE);
  590.     else
  591.         pCmdUI->Enable(FALSE);
  592. }
  593.  
  594.  
  595. void CDxtexView::OnUpdateViewSmallerMipLevel(CCmdUI* pCmdUI)
  596. {
  597.     if (m_lwMipCur < (LONG)GetDocument()->NumMips() - 1)
  598.         pCmdUI->Enable(TRUE);
  599.     else
  600.         pCmdUI->Enable(FALSE);
  601. }
  602.  
  603.  
  604. void CDxtexView::OnViewZoomIn()
  605. {
  606.     if (m_fZoom < 8.0f)
  607.         m_fZoom *= 2.0f;
  608.     m_rcDest.right = (LONG)(m_rcSrc.right * m_fZoom);
  609.     m_rcDest.bottom = (LONG)(m_rcSrc.bottom * m_fZoom);
  610.     SetScrollSizes(MM_TEXT, CSize(m_rcDest.Width(), m_rcDest.Height()));
  611.     m_bTitleModsChanged = TRUE; // force title bar update
  612.     Invalidate(); // force redraw of this view
  613. }
  614.  
  615.  
  616. void CDxtexView::OnViewZoomOut()
  617. {
  618.     if (m_fZoom > 0.125f)
  619.         m_fZoom /= 2.0f;
  620.     m_rcDest.right = (LONG)(m_rcSrc.right * m_fZoom);
  621.     m_rcDest.bottom = (LONG)(m_rcSrc.bottom * m_fZoom);
  622.     SetScrollSizes(MM_TEXT, CSize(m_rcDest.Width(), m_rcDest.Height()));
  623.     m_bTitleModsChanged = TRUE; // force title bar update
  624.     Invalidate(); // force redraw of this view
  625. }
  626.  
  627.  
  628. void CDxtexView::OnUpdateViewZoomIn(CCmdUI* pCmdUI)
  629. {
  630.     pCmdUI->Enable(m_fZoom < 8.0f);
  631. }
  632.  
  633.  
  634. void CDxtexView::OnUpdateViewZoomOut(CCmdUI* pCmdUI)
  635. {
  636.     pCmdUI->Enable(m_fZoom > 0.125f);
  637. }
  638.  
  639.  
  640. CString CDxtexView::GetStrTitleMods(VOID)
  641. {
  642.     CString strTitleMods;
  643.     strTitleMods = "(";
  644.  
  645.     // Append alpha, if in alpha mode
  646.     if (m_bViewAlpha)
  647.             strTitleMods += "Alpha, ";
  648.  
  649.     // Show format
  650.     LPDIRECT3DBASETEXTURE9 ptex;
  651.     CString strFormat;
  652.     D3DFORMAT fmt;
  653.  
  654.     if (m_bViewOrig)
  655.         ptex = GetDocument()->PtexOrig();
  656.     else
  657.         ptex = GetDocument()->PtexNew();
  658.  
  659.     if (GetDocument()->IsVolumeMap())
  660.     {
  661.         D3DVOLUME_DESC vd;
  662.         ((LPDIRECT3DVOLUMETEXTURE9)ptex)->GetLevelDesc(0, &vd);
  663.         fmt = vd.Format;
  664.     }
  665.     else if (!GetDocument()->IsCubeMap())
  666.     {
  667.         D3DSURFACE_DESC sd;
  668.         ((LPDIRECT3DTEXTURE9)ptex)->GetLevelDesc(0, &sd);
  669.         fmt = sd.Format;
  670.     }
  671.     else
  672.     {
  673.         D3DSURFACE_DESC sd;
  674.         ((LPDIRECT3DCUBETEXTURE9)ptex)->GetLevelDesc(0, &sd);
  675.         fmt = sd.Format;
  676.     }
  677.  
  678.     strTitleMods += FormatName(fmt);
  679.     strTitleMods += TEXT(", ");
  680.  
  681.     // Append cube map info, if a cube map
  682.     switch (m_CubeFaceCur)
  683.     {
  684.     case D3DCUBEMAP_FACE_NEGATIVE_X:
  685.         strTitleMods += "Negative X, ";
  686.         break;
  687.     case D3DCUBEMAP_FACE_POSITIVE_X:
  688.         strTitleMods += "Positive X, ";
  689.         break;
  690.     case D3DCUBEMAP_FACE_NEGATIVE_Y:
  691.         strTitleMods += "Negative Y, ";
  692.         break;
  693.     case D3DCUBEMAP_FACE_POSITIVE_Y:
  694.         strTitleMods += "Positive Y, ";
  695.         break;
  696.     case D3DCUBEMAP_FACE_NEGATIVE_Z:
  697.         strTitleMods += "Negative Z, ";
  698.         break;
  699.     case D3DCUBEMAP_FACE_POSITIVE_Z:
  700.         strTitleMods += "Positive Z, ";
  701.         break;
  702.     }
  703.  
  704.     if (m_lwSliceCur >= 0)
  705.     {
  706.         CString strSlice;
  707.         strSlice.Format("Slice %d of %d, ", m_lwSliceCur + 1, GetDocument()->DwDepthAt(m_lwMipCur));
  708.         strTitleMods += strSlice;
  709.     }
  710.  
  711.     // Append mip info, if multiple mip levels
  712.     DWORD dwNumMips = GetDocument()->NumMips();
  713.     if (dwNumMips > 1)
  714.     {
  715.         CString strMipInfo;
  716.         strMipInfo.Format("Mip %d of %d, ", m_lwMipCur + 1, dwNumMips);
  717.         strTitleMods += strMipInfo;
  718.     }
  719.  
  720.     // Append view magnification
  721.     CString strView;
  722.     strView.Format("%d", (LONG)(100 * m_fZoom));
  723.     strTitleMods += strView + "%";
  724.  
  725.     strTitleMods += ")";
  726.     return strTitleMods;
  727. }
  728.  
  729.  
  730. CString CDxtexView::FormatName(D3DFORMAT fmt)
  731. {
  732.     CString str = TEXT("Unknown fmt");
  733.  
  734.     for( int i=0; i < fmtInfoArraySize; i++ )
  735.     {
  736.         if( fmtInfoArray[i].fmt == fmt )
  737.         {
  738.             str = fmtInfoArray[i].strName;
  739.             break;
  740.         }
  741.     }
  742.     
  743.     return str;
  744. }
  745.  
  746. void CDxtexView::OnViewChangeBackgroundColor()
  747. {
  748.     CHOOSECOLOR cc;
  749.     COLORREF crArray[16];
  750.  
  751.     ZeroMemory(&cc, sizeof(cc));
  752.     cc.lStructSize = sizeof(cc);
  753.     cc.hwndOwner = GetSafeHwnd();
  754.     cc.rgbResult = PDxtexApp()->GetProfileInt("Settings", "Background Color", RGB(0, 255, 255));
  755.     cc.lpCustColors = crArray;
  756.     cc.Flags = CC_RGBINIT | CC_ANYCOLOR | CC_FULLOPEN;
  757.  
  758.     if (ChooseColor(&cc))
  759.     {
  760.         PDxtexApp()->WriteProfileInt("Settings", "Background Color", cc.rgbResult);
  761.  
  762.         // Update all views of all documents of our one doc template
  763.         POSITION posTemp = PDxtexApp()->GetFirstDocTemplatePosition();
  764.         CDocTemplate* pDocTemplate = PDxtexApp()->GetNextDocTemplate(posTemp);
  765.         CDocument* pdoc;
  766.         POSITION pos = pDocTemplate->GetFirstDocPosition();
  767.         while (pos != NULL)
  768.         {
  769.             pdoc = pDocTemplate->GetNextDoc(pos);
  770.             pdoc->UpdateAllViews(NULL, 2);
  771.         }
  772.     }
  773. }
  774.  
  775.  
  776. void CDxtexView::OnFileOpenSubsurface()
  777. {
  778.     GetDocument()->OpenSubsurface(m_CubeFaceCur, m_lwMipCur, m_lwSliceCur);
  779. }
  780.  
  781.  
  782. void CDxtexView::OnUpdateFileOpenSubsurface(CCmdUI* pCmdUI)
  783. {
  784.     pCmdUI->Enable(TRUE);
  785. }
  786.  
  787.  
  788. void CDxtexView::OnFileOpenAlphaSubsurface()
  789. {
  790.     GetDocument()->OpenAlphaSubsurface(m_CubeFaceCur, m_lwMipCur, m_lwSliceCur);
  791. }
  792.  
  793.  
  794. void CDxtexView::OnUpdateFileOpenAlphaSubsurface(CCmdUI* pCmdUI)
  795. {
  796.     pCmdUI->Enable(TRUE);
  797. }
  798.  
  799.  
  800. HRESULT CDxtexView::BuildViewSurface(BOOL bOrig, D3DCUBEMAP_FACES FaceType, LONG lwSlice, LONG lwMip, BOOL bViewAlpha)
  801. {
  802.     HRESULT hr;
  803.     LPDIRECT3DDEVICE9 pd3ddev = PDxtexApp()->Pd3ddev();
  804.     LPDIRECT3DBASETEXTURE9 ptex;
  805.     BOOL bIsCubeMap = GetDocument()->IsCubeMap();
  806.     BOOL bIsVolumeMap = GetDocument()->IsVolumeMap();
  807.     D3DSURFACE_DESC sd;
  808.     D3DVOLUME_DESC vd;
  809.  
  810.     ReleasePpo(&m_ptexCur);
  811.  
  812.     if (bIsVolumeMap && lwSlice == -1)
  813.         lwSlice = 0;
  814.  
  815.     if (bIsCubeMap && FaceType == D3DCUBEMAP_FACE_FORCE_DWORD)
  816.         FaceType = D3DCUBEMAP_FACE_POSITIVE_X;
  817.  
  818.     m_bViewOrig = bOrig;
  819.     m_bViewAlpha = bViewAlpha;
  820.     m_lwSliceCur = lwSlice;
  821.     m_lwMipCur = lwMip;
  822.     m_CubeFaceCur = FaceType;
  823.  
  824.     if (bOrig)
  825.         ptex = GetDocument()->PtexOrig();
  826.     else
  827.         ptex = GetDocument()->PtexNew();
  828.  
  829.     if (bIsVolumeMap)
  830.     {
  831.         ((LPDIRECT3DVOLUMETEXTURE9)ptex)->GetLevelDesc(m_lwMipCur, &vd);
  832.         sd.Width = vd.Width;
  833.         sd.Height = vd.Height;
  834.     }
  835.     else if (!bIsCubeMap)
  836.     {
  837.         ((LPDIRECT3DTEXTURE9)ptex)->GetLevelDesc(m_lwMipCur, &sd);
  838.     }
  839.     else
  840.     {
  841.         ((LPDIRECT3DCUBETEXTURE9)ptex)->GetLevelDesc(m_lwMipCur, &sd);
  842.     }
  843.  
  844.     hr = pd3ddev->CreateTexture(sd.Width, sd.Height, 1,
  845.          0 /* Usage */, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &m_ptexCur, NULL);
  846.     if (FAILED(hr))
  847.         return hr;
  848.  
  849.     m_rcSrc.SetRect(0, 0, sd.Width, sd.Height);
  850.     m_rcDest.SetRect(0, 0, (INT)(sd.Width * m_fZoom), (INT)(sd.Height * m_fZoom));
  851.  
  852.     LPDIRECT3DSURFACE9 psurfSrc = NULL;
  853.     LPDIRECT3DSURFACE9 psurfDest = NULL;
  854.  
  855.     hr = m_ptexCur->GetSurfaceLevel(0, &psurfDest);
  856.  
  857.     if (bIsVolumeMap)
  858.     {
  859.         LPDIRECT3DVOLUME9 pvolSrc;
  860.         hr = ((LPDIRECT3DVOLUMETEXTURE9)ptex)->GetVolumeLevel(m_lwMipCur, &pvolSrc);
  861.         hr = LoadSurfaceFromVolumeSlice(pvolSrc, m_lwSliceCur, psurfDest);
  862.         ReleasePpo(&pvolSrc);
  863.     }
  864.     else if (!bIsCubeMap)
  865.     {
  866.         hr = ((LPDIRECT3DTEXTURE9)ptex)->GetSurfaceLevel(m_lwMipCur, &psurfSrc);
  867.         hr = D3DXLoadSurfaceFromSurface(psurfDest, NULL, NULL, psurfSrc, NULL, NULL,
  868.             D3DX_FILTER_TRIANGLE, 0);
  869.     }
  870.     else
  871.     {
  872.         hr = ((LPDIRECT3DCUBETEXTURE9)ptex)->GetCubeMapSurface(FaceType, m_lwMipCur, &psurfSrc);
  873.         hr = D3DXLoadSurfaceFromSurface(psurfDest, NULL, NULL, psurfSrc, NULL, NULL,
  874.             D3DX_FILTER_TRIANGLE, 0);
  875.     }
  876.  
  877.  
  878.     if (bViewAlpha)
  879.     {
  880.         // Move alpha channels into RGB (and set alpha to 0xff)
  881.         D3DLOCKED_RECT lr;
  882.  
  883.         hr = psurfDest->LockRect(&lr, NULL, 0);
  884.  
  885.         DWORD xp;
  886.         DWORD yp;
  887.         DWORD* pdwRow = (DWORD*)lr.pBits;
  888.         DWORD* pdw;
  889.         DWORD dwAlpha;
  890.         LONG dataBytesPerRow = 4 * sd.Width;
  891.  
  892.         for (yp = 0; yp < sd.Height; yp++)
  893.         {
  894.             pdw = pdwRow;
  895.             for (xp = 0; xp < sd.Width; xp++)
  896.             {
  897.                 dwAlpha = *pdw >> 24;
  898.                 *pdw = 0xff000000 | (dwAlpha << 16) | (dwAlpha << 8) | (dwAlpha);
  899.                 pdw++;
  900.             }
  901.             pdwRow += lr.Pitch / 4;
  902.         }
  903.         psurfDest->UnlockRect();
  904.     }
  905.  
  906.     ReleasePpo(&psurfSrc);
  907.     ReleasePpo(&psurfDest);
  908.  
  909.     return S_OK;
  910. }
  911.  
  912.  
  913. HRESULT CDxtexView::LoadSurfaceFromVolumeSlice(LPDIRECT3DVOLUME9 pVolume, UINT iSlice, LPDIRECT3DSURFACE9 psurf)
  914. {
  915.     HRESULT hr;
  916.     D3DVOLUME_DESC vd;
  917.     D3DLOCKED_BOX lb;
  918.     D3DBOX box;
  919.     RECT rc;
  920.  
  921.     pVolume->GetDesc(&vd);
  922.  
  923.     box.Left = 0;
  924.     box.Right = vd.Width;
  925.     box.Top = 0;
  926.     box.Bottom = vd.Height;
  927.     box.Front = iSlice;
  928.     box.Back = iSlice + 1;
  929.  
  930.     rc.left = 0;
  931.     rc.right = vd.Width;
  932.     rc.top = 0;
  933.     rc.bottom = vd.Height;
  934.  
  935.     hr = pVolume->LockBox(&lb, &box, 0);
  936.     if (FAILED(hr))
  937.         return hr;
  938.  
  939.     hr = D3DXLoadSurfaceFromMemory(psurf, NULL, NULL, lb.pBits, vd.Format, lb.RowPitch,
  940.         NULL, &rc, D3DX_FILTER_TRIANGLE, 0);
  941.  
  942.     pVolume->UnlockBox();
  943.  
  944.     return hr;
  945. }
  946.  
  947.  
  948. void CDxtexView::OnViewNegX()
  949. {
  950.     BuildViewSurface(m_bViewOrig, D3DCUBEMAP_FACE_NEGATIVE_X, m_lwSliceCur, m_lwMipCur, m_bViewAlpha);
  951.     m_bTitleModsChanged = TRUE; // force title bar update
  952.     RenderScene();
  953.     Invalidate(); // force redraw of this view
  954. }
  955.  
  956.  
  957. void CDxtexView::OnUpdateViewNegX(CCmdUI* pCmdUI)
  958. {
  959.     BOOL bEnable = GetDocument()->IsCubeMap();
  960.     pCmdUI->Enable(bEnable);
  961.     pCmdUI->SetCheck(m_CubeFaceCur == D3DCUBEMAP_FACE_NEGATIVE_X);
  962. }
  963.  
  964.  
  965. void CDxtexView::OnViewPosX()
  966. {
  967.     BuildViewSurface(m_bViewOrig, D3DCUBEMAP_FACE_POSITIVE_X, m_lwSliceCur, m_lwMipCur, m_bViewAlpha);
  968.     m_bTitleModsChanged = TRUE; // force title bar update
  969.     RenderScene();
  970.     Invalidate(); // force redraw of this view
  971. }
  972.  
  973.  
  974. void CDxtexView::OnUpdateViewPosX(CCmdUI* pCmdUI)
  975. {
  976.     BOOL bEnable = GetDocument()->IsCubeMap();
  977.     pCmdUI->Enable(bEnable);
  978.     pCmdUI->SetCheck(m_CubeFaceCur == D3DCUBEMAP_FACE_POSITIVE_X);
  979. }
  980.  
  981.  
  982. void CDxtexView::OnViewNegY()
  983. {
  984.     BuildViewSurface(m_bViewOrig, D3DCUBEMAP_FACE_NEGATIVE_Y, m_lwSliceCur, m_lwMipCur, m_bViewAlpha);
  985.     m_bTitleModsChanged = TRUE; // force title bar update
  986.     RenderScene();
  987.     Invalidate(); // force redraw of this view
  988. }
  989.  
  990.  
  991. void CDxtexView::OnUpdateViewNegY(CCmdUI* pCmdUI)
  992. {
  993.     BOOL bEnable = GetDocument()->IsCubeMap();
  994.     pCmdUI->Enable(bEnable);
  995.     pCmdUI->SetCheck(m_CubeFaceCur == D3DCUBEMAP_FACE_NEGATIVE_Y);
  996. }
  997.  
  998.  
  999. void CDxtexView::OnViewPosY()
  1000. {
  1001.     BuildViewSurface(m_bViewOrig, D3DCUBEMAP_FACE_POSITIVE_Y, m_lwSliceCur, m_lwMipCur, m_bViewAlpha);
  1002.     m_bTitleModsChanged = TRUE; // force title bar update
  1003.     RenderScene();
  1004.     Invalidate(); // force redraw of this view
  1005. }
  1006.  
  1007.  
  1008. void CDxtexView::OnUpdateViewPosY(CCmdUI* pCmdUI)
  1009. {
  1010.     BOOL bEnable = GetDocument()->IsCubeMap();
  1011.     pCmdUI->Enable(bEnable);
  1012.     pCmdUI->SetCheck(m_CubeFaceCur == D3DCUBEMAP_FACE_POSITIVE_Y);
  1013. }
  1014.  
  1015.  
  1016. void CDxtexView::OnViewNegZ()
  1017. {
  1018.     BuildViewSurface(m_bViewOrig, D3DCUBEMAP_FACE_NEGATIVE_Z, m_lwSliceCur, m_lwMipCur, m_bViewAlpha);
  1019.     m_bTitleModsChanged = TRUE; // force title bar update
  1020.     RenderScene();
  1021.     Invalidate(); // force redraw of this view
  1022. }
  1023.  
  1024.  
  1025. void CDxtexView::OnUpdateViewNegZ(CCmdUI* pCmdUI)
  1026. {
  1027.     BOOL bEnable = GetDocument()->IsCubeMap();
  1028.     pCmdUI->Enable(bEnable);
  1029.     pCmdUI->SetCheck(m_CubeFaceCur == D3DCUBEMAP_FACE_NEGATIVE_Z);
  1030. }
  1031.  
  1032.  
  1033. void CDxtexView::OnViewPosZ()
  1034. {
  1035.     BuildViewSurface(m_bViewOrig, D3DCUBEMAP_FACE_POSITIVE_Z, m_lwSliceCur, m_lwMipCur, m_bViewAlpha);
  1036.     m_bTitleModsChanged = TRUE; // force title bar update
  1037.     RenderScene();
  1038.     Invalidate(); // force redraw of this view
  1039. }
  1040.  
  1041.  
  1042. void CDxtexView::OnUpdateViewPosZ(CCmdUI* pCmdUI)
  1043. {
  1044.     BOOL bEnable = GetDocument()->IsCubeMap();
  1045.     pCmdUI->Enable(bEnable);
  1046.     pCmdUI->SetCheck(m_CubeFaceCur == D3DCUBEMAP_FACE_POSITIVE_Z);
  1047. }
  1048.  
  1049. void CDxtexView::OnFileOpenFace()
  1050. {
  1051.     GetDocument()->OpenCubeFace(m_CubeFaceCur);
  1052. }
  1053.  
  1054. void CDxtexView::OnUpdateFileOpenFace(CCmdUI* pCmdUI)
  1055. {
  1056.     BOOL bEnable = (m_CubeFaceCur != D3DCUBEMAP_FACE_FORCE_DWORD);
  1057.     pCmdUI->Enable(bEnable);
  1058. }
  1059.  
  1060. void CDxtexView::OnFileOpenAlphaFace()
  1061. {
  1062.     GetDocument()->OpenAlphaCubeFace(m_CubeFaceCur);
  1063. }
  1064.  
  1065. void CDxtexView::OnUpdateFileOpenAlphaFace(CCmdUI* pCmdUI)
  1066. {
  1067.     BOOL bEnable = (m_CubeFaceCur != D3DCUBEMAP_FACE_FORCE_DWORD);
  1068.     pCmdUI->Enable(bEnable);
  1069. }
  1070.  
  1071. void CDxtexView::OnViewHigherVolumeSlice()
  1072. {
  1073.     m_lwSliceCur++;
  1074.     BuildViewSurface(m_bViewOrig, m_CubeFaceCur, m_lwSliceCur, m_lwMipCur, m_bViewAlpha);
  1075.     UpdateDevice();
  1076.     RenderScene();
  1077.     m_bTitleModsChanged = TRUE; // force title bar update
  1078.     Invalidate(); // force redraw of this view
  1079. }
  1080.  
  1081. void CDxtexView::OnUpdateViewHigherVolumeSlice(CCmdUI* pCmdUI)
  1082. {
  1083.     pCmdUI->Enable(GetDocument()->IsVolumeMap() && m_lwSliceCur < (LONG)GetDocument()->DwDepthAt(m_lwMipCur) - 1);
  1084. }
  1085.  
  1086. void CDxtexView::OnViewLowerVolumeSlice()
  1087. {
  1088.     m_lwSliceCur--;
  1089.     BuildViewSurface(m_bViewOrig, m_CubeFaceCur, m_lwSliceCur, m_lwMipCur, m_bViewAlpha);
  1090.     UpdateDevice();
  1091.     RenderScene();
  1092.     m_bTitleModsChanged = TRUE; // force title bar update
  1093.     Invalidate(); // force redraw of this view
  1094. }
  1095.  
  1096. void CDxtexView::OnUpdateViewLowerVolumeSlice(CCmdUI* pCmdUI)
  1097. {
  1098.     pCmdUI->Enable(GetDocument()->IsVolumeMap() && m_lwSliceCur > 0);
  1099. }
  1100.  
  1101.